/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 sound_volume.h

	$Header: /heroes4/sound_volume.h $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )
#include "music.h"

#include <vector>
#include "elements_of.h"
#include "playing_sound.h"
#include "sound.h"
#include "sound_cache.h"
#include "sound_configurations.h"
#include "terrain.h"

static int g_music_volume = 0;

namespace
{
	struct t_sound_pair
	{
		t_sound_cache       cache;
		t_playing_sound_ptr sound;
	};

	static std::vector<t_sound_pair> g_music_list;

	t_sound_pair g_playing_music;
};

t_sound_cache get_music_playing()
{
	return g_playing_music.cache;
}

t_playing_sound_ptr get_music_playing_pointer()
{
	return g_playing_music.sound;
}


int  get_music_volume()
{
	return g_music_volume;
}


void set_music_volume( int value )
{
	g_music_volume = value;
	if (g_playing_music.sound != 0)
	{
		if (g_playing_music.sound->is_playing())
		{
			g_playing_music.sound->set_volume( value );
			if (value <= -10000)
				g_playing_music.sound->stop();
		}
		else
			g_playing_music.sound->play( g_music_volume, true, false );
	}
}

void play_sound( t_sound& sound )
{
	if (g_sound_volume > -10000)
		sound.play( g_sound_volume );
}

// ----------------------------------------------------------------------
// ----------------------------------------------------------------------

void clear_music_cache()
{
	int i;
	t_sound_pair g_dead_music;

		// look for this sound in the list of old music we've played.
	for (i = g_music_list.size() - 1; i >= 0; i--)
	{
		g_dead_music = g_music_list[i];
		if (g_dead_music.sound != 0)
			g_dead_music.sound->stop();
	}
}

void play_music( t_sound_cache const& cache )
{
	if (cache == g_playing_music.cache)
	{
		if (g_playing_music.sound != 0)
		{
			if (!g_playing_music.sound->is_playing() || g_playing_music.sound->is_fading_out())
			{
				g_playing_music.sound->play( g_music_volume, true, true );
			}
		}
		return;
	}
	// fade old music, if any, out.
	if (g_playing_music.sound != 0 && g_playing_music.sound->is_playing())
		g_playing_music.sound->fade_out();

	if (!cache.is_valid())
		return;

	int i;

	// look for this sound in the list of old music we've played.
	for (i = g_music_list.size() - 1; i >= 0; i--)
	{
		if (g_music_list[i].cache == cache)
			break;
	}
	// if found, restart the old version at the old position.
	if ( i >= 0 )
	{
		g_playing_music = g_music_list[i];
		if (g_playing_music.sound != 0)
			g_playing_music.sound->play( g_music_volume, true, true );
		return;
	}

	// if not found, create a new entry, and a new sound buffer.
	t_sound_ptr sound;

	g_playing_music.cache = cache;
	sound = cache.get();
	if (sound != 0)
		g_playing_music.sound = sound->play( g_music_volume, true, true );
	else
		g_playing_music.sound = 0;
	g_music_list.push_back( g_playing_music );
}

// ----------------------------------------------------
// stop music
// ----------------------------------------------------
void stop_music()
{
	t_sound_cache stop;

	play_music( stop );
}


// ----------------------------------------------------
// set music for each terrain
// ----------------------------------------------------
void set_music( t_terrain_type terrain )
{
	static t_sound_cache const k_terrain_sound[] =
	{
		"terrain.water",
		"terrain.grass",
		"terrain.rough",
		"terrain.swamp",
		"terrain.volcanic",
		"terrain.snow",
		"terrain.sand",
		"terrain.dirt",
		"terrain.subterranean",
	};

	play_music( k_terrain_sound[ get_basic_terrain( terrain ) ] );
};

